import * as vscode from 'vscode';
import * as fs from 'fs';
import * as path from 'path';

export interface Snippet {
    id: string;
    name: string;
    description: string;
    language: string;
    code: string;
    tags: string[];
    group: string;
    createdAt: Date;
    updatedAt: Date;
}

export class SnippetManager {
    private snippets: Snippet[] = [];
    private storagePath: string;

    constructor(private context: vscode.ExtensionContext) {
        this.storagePath = this.getStoragePath();
        this.loadSnippets();
    }

    private getStoragePath(): string {
        const config = vscode.workspace.getConfiguration('snippetManager');
        const customPath = config.get<string>('storagePath');
        
        if (customPath && customPath.trim()) {
            return customPath;
        }
        
        return path.join(this.context.globalStorageUri.fsPath, 'snippets.json');
    }

    private async loadSnippets() {
        try {
            if (fs.existsSync(this.storagePath)) {
                const data = fs.readFileSync(this.storagePath, 'utf8');
                const parsed = JSON.parse(data);
                this.snippets = parsed.map((item: any) => ({
                    ...item,
                    createdAt: new Date(item.createdAt),
                    updatedAt: new Date(item.updatedAt)
                }));
            }
        } catch (error) {
            console.error('Failed to load snippets:', error);
            this.snippets = [];
        }
    }

    private async saveSnippets() {
        try {
            const dir = path.dirname(this.storagePath);
            if (!fs.existsSync(dir)) {
                fs.mkdirSync(dir, { recursive: true });
            }
            
            fs.writeFileSync(
                this.storagePath,
                JSON.stringify(this.snippets, null, 2),
                'utf8'
            );
        } catch (error) {
            vscode.window.showErrorMessage(`Failed to save snippets: ${error}`);
        }
    }

    getAllSnippets(): Snippet[] {
        return [...this.snippets];
    }

    getSnippetsByGroup(group: string): Snippet[] {
        return this.snippets.filter(s => s.group === group);
    }

    getGroups(): string[] {
        const groups = new Set(this.snippets.map(s => s.group));
        return Array.from(groups).sort();
    }

    searchSnippets(query: string): Snippet[] {
        const lowercaseQuery = query.toLowerCase();
        return this.snippets.filter(snippet =>
            snippet.name.toLowerCase().includes(lowercaseQuery) ||
            snippet.description.toLowerCase().includes(lowercaseQuery) ||
            snippet.code.toLowerCase().includes(lowercaseQuery) ||
            snippet.tags.some(tag => tag.toLowerCase().includes(lowercaseQuery))
        );
    }

    async createSnippet(snippet: Omit<Snippet, 'id' | 'createdAt' | 'updatedAt'>): Promise<Snippet> {
        const newSnippet: Snippet = {
            ...snippet,
            id: this.generateId(),
            createdAt: new Date(),
            updatedAt: new Date()
        };
        
        this.snippets.push(newSnippet);
        await this.saveSnippets();
        return newSnippet;
    }

    async updateSnippet(id: string, updates: Partial<Snippet>): Promise<boolean> {
        const index = this.snippets.findIndex(s => s.id === id);
        if (index === -1) return false;
        
        this.snippets[index] = {
            ...this.snippets[index],
            ...updates,
            id,
            updatedAt: new Date()
        };
        
        await this.saveSnippets();
        return true;
    }

    async deleteSnippet(id: string): Promise<boolean> {
        const index = this.snippets.findIndex(s => s.id === id);
        if (index === -1) return false;
        
        this.snippets.splice(index, 1);
        await this.saveSnippets();
        return true;
    }

    async exportSnippets(filePath: string): Promise<void> {
        const data = JSON.stringify(this.snippets, null, 2);
        fs.writeFileSync(filePath, data, 'utf8');
    }

    async importSnippets(filePath: string): Promise<void> {
        const data = fs.readFileSync(filePath, 'utf8');
        const importedSnippets = JSON.parse(data);
        
        // 验证导入的数据
        const validSnippets = importedSnippets.map((item: any) => ({
            ...item,
            id: this.generateId(), // 重新生成ID避免冲突
            createdAt: new Date(item.createdAt),
            updatedAt: new Date(item.updatedAt)
        }));
        
        this.snippets = [...this.snippets, ...validSnippets];
        await this.saveSnippets();
    }

    private generateId(): string {
        return Date.now().toString(36) + Math.random().toString(36).substr(2);
    }
}
